package beautiful.butterfly.drds.data_exchange.statistics;

import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;

import java.util.Date;

@Slf4j
@SuppressWarnings("NullableProblems")
public class RunningInfo implements Comparable<RunningInfo>
{
    private static String datetimeFormat = "yyyy-MM-dd HH:mm:ss";
    //
    @Setter
    @Getter
    private final int taskGroupId;
    @Setter
    @Getter
    private final int taskId;
    @Setter
    @Getter
    private final Phase phase;
    //
    @Setter
    @Getter
    private volatile Action action;
    //
    @Setter
    @Getter
    private volatile Date startDate;
    @Setter
    @Getter
    private volatile long startDateNanoTime;
    @Setter
    @Getter
    private volatile long $nanoTime = -1;
    //
    @Setter
    @Getter
    private volatile long count = 0;
    @Setter
    @Getter
    private volatile long size = 0;


    public RunningInfo(int taskGroupId, int taskId, Phase phase)
    {
        this.taskGroupId = taskGroupId;
        this.taskId = taskId;
        this.phase = phase;
    }

    //new
    public static void addPerfRecord(int taskGroupId, int taskId, Phase phase, long startDateTimeLong, long $nanoTime)
    {
        if (PerfTrace.getInstance().isEnable())
        {
            RunningInfo runningInfo = new RunningInfo(taskGroupId, taskId, phase);
            runningInfo.$nanoTime = $nanoTime;
            runningInfo.action = Action.end;
            runningInfo.startDate = new Date(startDateTimeLong);
            //在PerfTrace里注册
            PerfTrace.getInstance().tracePerfRecord(runningInfo);
            log.info(runningInfo.toString());
        }
    }

    public void start()
    {
        if (PerfTrace.getInstance().isEnable())
        {
            this.startDate = new Date();
            this.startDateNanoTime = System.nanoTime();
            this.action = Action.start;
            //在PerfTrace里注册
            PerfTrace.getInstance().tracePerfRecord(this);
            log.info(toString());
        }
    }

    public void end()
    {
        if (PerfTrace.getInstance().isEnable())
        {
            this.$nanoTime = System.nanoTime() - startDateNanoTime;
            this.action = Action.end;
            PerfTrace.getInstance().tracePerfRecord(this);
            log.info(toString());
        }
    }

    public void end(long $nanoTime)
    {
        if (PerfTrace.getInstance().isEnable())
        {
            this.$nanoTime = $nanoTime;
            this.action = Action.end;
            PerfTrace.getInstance().tracePerfRecord(this);
            log.info(toString());
        }
    }

    public void addCount(long count)
    {
        this.count += count;
    }

    public void addSize(long size)
    {
        this.size += size;
    }


    public String toString()
    {
        return String.format("%s,%s,%s,%s,%s,%s,%s,%s,%s,%s"
                , getInstId(), taskGroupId, taskId, phase, action,
                DateFormatUtils.format(startDate, datetimeFormat), $nanoTime, count, size, getHostIP());
    }


    public int compareTo(RunningInfo o)
    {
        if (o == null)
        {
            return 1;
        }
        return this.$nanoTime > o.$nanoTime ? 1 : this.$nanoTime == o.$nanoTime ? 0 : -1;
    }


    public long getInstId()
    {
        return PerfTrace.getInstance().getInstId();
    }

    public String getHostIP()
    {
        return null;
    }


}
